<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <p>策略模式：封装了一系列策略</p>
    <p>策略：就是算法</p>
  </body>
</html>
<script>
  // 公司年终奖例子
  /*
  评分等级：S、A、B
  年终奖对应奖金：4倍、3倍、2倍
  计算出对应等级的年终奖
  */

  // calculateBonus 计算奖金
  // performanceLevel 评分等级
  // salary 工资

  // 如果增添了或更改了 对应的评分等级，对应奖金 ，就要在函数里从新增 if 都要更改当前的原函数
  /* 这样的代码会有以下三个问题:
  calculateBonus函数比较庞大，包含需要if-else语句，难以维护。
  calculateBonus函数缺乏灵活的弹性，如果需要增加策略，还需要通读函数内部实现，违反了开放-封闭原则。
  算法无复用性，在程序的其他地方需要重用，只能复制粘贴*/

  var calculateBonus = function (performanceLevel, salary) {
    if (performanceLevel === "S") {
      // 算法也就是它对应的策略
      return salary * 4;
    }
    if (performanceLevel === "A") {
      return salary * 3;
    }
    if (performanceLevel === "B") {
      return salary * 2;
    }
  };
  console.log(calculateBonus("S", 20000));

  // 将策略分离出来
  // 在 js 当中函数就是对象
  var strategies = {
    s: function (salary) {
      return salary * 4;
    },
    A: function (salary) {
      return salary * 3;
    },
    B: function (salary) {
      return salary * 2;
    },
  };

  var calculateBonus = function (performanceLevel, salary) {
    // 返回的是
    return strategies[performanceLevel](salary);
  };
  console.log(calculateBonus("S", 20000));
  console.log(calculateBonus("A", 20000));
  console.log(calculateBonus("B", 20000));

  //   优点：

  // 1、策略模式符合开闭原则。

  // 2、避免使用多重条件转移语句，如if...else...语句、switch 语句

  // 3、使用策略模式可以提高算法的保密性和安全性。

  // 缺点：

  // 1、客户端必须知道所有的策略，并且自行决定使用哪一个策略类。

  // 2、代码中会产生非常多策略类，增加维护难度。
</script>
